# 导入模型类
from info.models import User, News,Category
from info.utils.commons import login_required
from info.utils.response_code import RET
# 导入常用数据
from info import constants, db
from . import news_api
# 导入上下文对象session
from flask import session, render_template, current_app, jsonify,request, g




# 项目首页视图函数
@news_api.route('/')
def index():
    """
    用户信息展示: 提取信息 处理信息 返回数据
    尝试从redis数据库获取用户id
    如果id存在,尝试从数据库获取用户数据
    传送数据给模板
    :return:
    """
    user_id = session.get('user_id')
    user, data = None, None
    if user_id:
        try:
            user = User.query.get(user_id)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg='数据库查询失败')

    """
    首页展示新闻点击排行
    尝试查询数据库,获取新闻根据点击数的倒叙排序
    遍历查找道德对象
    讲对象以字典的形式返回给前端
    """
    news_list = []
    try:
        news_list = News.query.filter().order_by(News.clicks.desc()).limit(6)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询失败')
    news_dict_list = []

    if not news_list:
        return jsonify(errno=RET.NODATA, errmsg='没有新闻数据')
    # 将新闻列表以字典形式传给前端
    for news in news_list:
        news_dict_list.append(news.to_dict())

    # 展示新闻分类数据
    """
    1 查询数据库获取分类数据
    2 查询到分类的数据放进分类字典里
    3 返回数据到前段
    """
    categories = None
    try:
        categories = Category.query.limit(6)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据查询失败')
    # 判断分类是否存在
    if not categories:
        return jsonify(errno=RET.DATAEXIST, errmsg='数据不存在')
    # 遍历分类对象加载到传给前端的列表中
    category_dict_list = []
    for category in categories:
        category_dict_list.append(category.to_dict())

    data = {
        'user_info': user.to_dict() if user else None,
        'news_dict_list': news_dict_list,
        'category_dict_list': category_dict_list
    }

    return render_template('news/index.html', data=data)


# 小图标视图
@news_api.route('/favicon.ico')
def favicon_ico():
    return current_app.send_static_file('news/favicon.ico')


#      首页展示新闻分类内容
@news_api.route('/news_list')
def get_news_list():
    """
    1 获取参数 cid page per_page
    2 将参数转化为int类型
    3 判断分类id大于1
    4
        1 根据分类查询数据库内容
        2 分页展示
        3 返回数据给前端
    """
    cid = request.args.get('cid', '1')
    page = request.args.get('page', '1')
    per_page = request.args.get('per_page', '10')
    # 强转参数为int类型
    try:
        cid, page, per_page = int(cid), int(page), int(per_page)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='参数格式错误')
    # 判断cid是否大于1
    filters = []
    if cid > 1:
        filters.append(News.category_id == cid)
        # filters.append(News.category_id == cid)
    try:
        paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page, constants.HOME_PAGE_MAX_NEWS, False)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询数据失败')
    news_list = paginate.items
    current_page = paginate.page
    total_page = paginate.pages

    # 创建新闻列表
    news_dict_list = []
    for news in news_list:
        news_dict_list.append(news.to_dict())
    # 返回数据
    data = {
        'news_dict_list': news_dict_list,
        'current_page': current_page,
        'total_page': total_page
    }
    return jsonify(errno=RET.OK, errmsg='获取数据成功', data=data)


# 新闻详情展示
@news_api.route('/<int:news_id>')
@login_required
def news_detail(news_id):
    """
    获取用户信息
    尝试根据news_id获取新闻
    给新闻点击量加1
    新闻的数据获取
    返回数据
    :param news_id:
    :return:
    """
    user = g.user

    # 尝试获取新闻
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询新闻信息失败')
    # 给新闻点击量加1
    news.clicks += 1
    # 尝试提交新闻点击量增加
    try:
        db.session.add(news)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='数据存储失败')
    # 拼接返回数据
    """
       详情页展示新闻分类后点击排行
       尝试查询数据库,获取新闻根据点击数的倒叙排序
       遍历查找
       讲对象以字典的形式返回给前端
       """
    # 查找新闻分类
    news_info = news.to_dict()
    news_category = news_info['category']['id']
    news_list = []
    try:
        news_list = News.query.filter(News.category_id==news_category).order_by(News.clicks.desc()).limit(6)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询失败')
    news_dict_list = []

    if not news_list:
        return jsonify(errno=RET.NODATA, errmsg='没有新闻数据')
    # 将新闻列表以字典形式传给前端
    for news_ in news_list:
        news_dict_list.append(news_.to_dict())
    # # 查询新闻是否已被收藏
    # is_collected = False
    # if news in user.collection_news:
    #     is_collected = True
    data = {
        'user_info': user.to_dict() if user else None,
        'news_detail': news.to_dict(),
        'news_dict_list': news_dict_list,
        # 'is_collected': is_collected
    }
    # 返回数据
    return render_template('news/detail.html', data=data)


@news_api.route('/news_collect', methods=['POST'])
@login_required
def news_collect():
    """
    新闻收藏功能
    1 获取用户数据
    2 用户如果不存在终止程序
    3 判断参数是否完整
    4 强转news_id
    5 判断action是否为collect或者cancel_collect
    6 尝试从数据库获取该新闻
    7 判断action是collect
    8 判断user是否收藏该新闻
    9 提交信息到数据库
    10 返回结果

    :return:
    """
    user = g.user
    if not user:
        return jsonify(errno=RET.NODATA, errmsg='用户未登录')
    # 判断参数完整性
    action = request.json.get('action')
    news_id = request.json.get('news_id')
    if not all([action, news_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
    # 强转news_id
    try:
        news_id = int(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='新闻id不正确')
    # 判断action是否为二者其一
    if action not in ['collect', 'cancel_collect']:
        return jsonify(errno=RET.PARAMERR, errmsg='提交参数输错')
    # 判断数据库中是否有该新闻
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='没有该新闻的数据')
    # 判断action为哪个
    if action == 'collect':
        if news not in user.collection_news:
            user.collection_news.append(news)
    else:
        user.collection_news.remove(news)
    # 尝试给数据库添加数据
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='保存数据失败')
    # 返回数据
    return jsonify(errno=RET.OK, errmsg='OK')


@news_api.route('/news_comment', methods=['GET', 'POST'])
@login_required
def news_comment():
    """
    判断用户是否登陆
    获取参数,

    :return:
    """
    pass
